﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using TA.DotNetUtils;
using System.Collections;

namespace TA.Turbo.Controls
{
	/// <summary>
	/// Renders the contents of the Repeater in server-side binding scenarios.
	/// </summary>
	public class RenderedItemsContainer : BaseRepeaterControl
	{
		internal RenderedItemsContainer(Repeater owner)
			: base(owner)
		{
		}
		/// <summary>
		/// Renders the contents.
		/// </summary>
		/// <param name="writer"></param>
		public override void RenderControl(HtmlTextWriter writer)
		{
			if (!string.IsNullOrEmpty(this.Repeater.ParseRenderedItems.Client) && this.Repeater.BindItem.Active)
			{
				IntRange entriesRange = this.Repeater.EnsureEntriesLoaded(this.Repeater.EntriesRange);
				MultipleInstanceTemplate t = this.Repeater.DisplayEdit ? this.Repeater.EditItem : this.Repeater.ViewItem;

				if (this.Repeater.Groupings.Count > 0)
				{
					List<EntryGroup> groups = new List<EntryGroup>();
					foreach (object entry in this.Repeater.Value.Entries)
					{
						DoGroup(groups, entry, 0);
					}

					int iEntry = 0;
					DoRender(writer, t, groups, 0, ref iEntry);
				}
				else
				{
					for (int i = entriesRange.Start; i < entriesRange.End; ++i)
					{
						this.Repeater.OnBindItem(new BindEventArgs(t.Container, this.Repeater.Value.Entries[i - this.Repeater.Value.FirstIndex]));
						t.Render(writer, (i - entriesRange.Start).ToString());
					}
				}
			}
			base.RenderControl(writer);
		}
		private void DoGroup(List<EntryGroup> groups, object entry, int iGrouping)
		{
			RepeaterGrouping grouping = this.Repeater.Groupings[iGrouping];

			EntryGroup existing = DoGroup_FindExisting(groups, entry, grouping);

			if (existing == null)
			{
				existing = new EntryGroup();
				groups.Add(existing);
			}

			existing.Entries.Add(entry);

			if (iGrouping < this.Repeater.Groupings.Count - 1)
			{
				DoGroup(existing.SubGroups, entry, iGrouping + 1);
			}
		}
		private EntryGroup DoGroup_FindExisting(List<EntryGroup> groups, object entry, RepeaterGrouping grouping)
		{
			EntryGroup existing = null;

			foreach (EntryGroup g in groups)
			{
				object oExisting = g.Entries[0];

				if (grouping.EntriesEqual(entry, oExisting))
				{
					existing = g;
					break;
				}
			}

			return existing;
		}
		private void DoRender(HtmlTextWriter writer, MultipleInstanceTemplate itemTemplate, List<EntryGroup> groups, int iGrouping, ref int iEntry)
		{
			RepeaterGrouping grouping = this.Repeater.Groupings[iGrouping];

			for (int iGroup = 0; iGroup < groups.Count; ++iGroup)
			{
				EntryGroup group = groups[iGroup];
				grouping.DoBind(iGroup, group);

				grouping.Header.Render(writer, grouping.Header.Container.ID + "_" + iGroup);

				if (iGrouping < this.Repeater.Groupings.Count - 1)
				{
					this.DoRender(writer, itemTemplate, group.SubGroups, iGrouping + 1, ref iEntry);
				}
				else
				{
					foreach (object o in group.Entries)
					{
						this.Repeater.OnBindItem(new BindEventArgs(itemTemplate.Container, o));
						itemTemplate.Render(writer, iEntry.ToString());

						++iEntry;
					}
				}

				grouping.Footer.Render(writer, grouping.Footer.Container.ID + "_" + iGroup);
			}
		}
	}

}
